<?php
/**
 * @author Erling Owe <erling.owe@gmail.com>
 * @package Core
 * @subpackage Presentation
 */


/**
 * This collection may hold widgets, elements or text.
 */
class Core_Presentation_HTML_NodeCollection extends ArrayObject {

    private function interpreter ( Core_Presentation_HTML_NodeCollection $objNodeCollection, $strExpression ) {
        
        if ( substr( $strExpression, 0, 1 ) == "#" ) {
            // NOTE: list() returns an error if $strSelectors is not set, hence the @.
            @list( $strId, $strSelectors ) = explode( " ", substr( $strExpression, 1 ) );
        } else {
            $strSelectors = $strExpression;
        }

        if ( $strId ) {

            if ( $strSelectors ) {
                // TODO: Gather all elements below the id in a new collection.
            } else {
                foreach ( $this as $objNode ) {
                    if ( $objNode instanceof Core_Presentation_HTML_Element ) {
                        if ( $objNode->getAttribute( "id" ) == $strId ) {
                            return $objNode;
                        }
                    }
                }
                throw new Exception ( "No element with the id '" . $strId . "' was found in the document." );
            }

        }

        $arrSelectors = explode( ",", $strSelectors );
        foreach ( $arrSelectors as $strSelector ) {
            $this->interpretOne( $objNodeCollection, $strSelector );
        }

    }

    private function interpretOne ( Core_Presentation_HTML_NodeCollection &$objNodeCollection, $strSelector ) {

    }


    /**
     * Gets a collection of all the nodes in this collection.
     *
     * If only one node is present in the collection, that node is returned
     * instead of a collection.
     *
     * @param string $strExpression Selectors.
     * @return Core_Presentation_HTML_NodeCollection
     */
    public function all ( $strExpression = null ) {
        return ( $strExpression ) ? $this->interpreter( $this, $strExpression ) : $this;
    }

    /**
     * Gets a collection of all the children of the elements in this collection.
     *
     * @param string $strExpression Selectors.
     * @return Core_Presentation_HTML_NodeCollection
     */
    public function children ( $strExpression = null ) {

        $objNodeCollection = new Core_Presentation_HTML_NodeCollection ();

        foreach ( $this as $objNode ) {
            if ( $objNode instanceof Core_Presentation_HTML_Element ) {
                foreach ( $objNode->children() as $objChildNode ) {
                    $objNodeCollection[] = $objChildNode ;
                }
            }
        }

        return ( $strExpression ) ? $this->interpreter( $objNodeCollection, $strExpression ) : $objNodeCollection;

    }

    // FIX find() WHEN EVERYTHING ELSE WORKS
    /**
     * Gets a collection of all the nodes in this collection and their decsendants.
     *
     * @param string $strExpression Selectors.
     * @return Core_Presentation_HTML_NodeCollection
     */
    public function find ( $strExpression = null ) {
        return ( $strExpression ) ? $this->interpreter( $this, $strExpression ) : $this;
    }

    /**
     * Sets an attribute to all the elements in the collection.
     *
     * @param string $strName
     * @param string $strValue
     */
    public function setAttribute ( $strName, $strValue ) {
        foreach ( $this as $objNode ) {
            if ( $objNode instanceof Core_Presentation_HTML_Element ) {
                $objElement->setAttribute( $strName, $strValue );
            }
        }
    }

}

?>
